package com.cctc.juc.source.Athread.threadlocal.DTransmittableThreadLocal;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlCopier;

import java.util.WeakHashMap;

/**
 * TransmittableThreadLocal [TTL 可传播的线程本地变量（ITL 的优化版）]
 * 1. TTL 继承自 ITL, 具体值仍然保存在线程内部的 inheritableThreadLocals，不涉及线程池时可以当成 InheritableThreadLocal 使用;
 * 2. 通过一个 Holder，可以找到 JVM 进程中每个线程当前所持有的 ThreadLocal 对象;
 * - Holder 的类型为  WeakHashMap<TransmittableThreadLocal<Object>, ?>，可以把它被当成一个 Set 使用（Value 永远为 null，用不到），存放的是所有和当前线程产生关联的 TTL，通过它可以找到 JVM 进程中每个线程当前所持有的 ThreadLocal 对象（即使用 WeakHashMap 收集线程中所有的 TTL）。
 * 3. 单纯的使用 TTL 是达不到支持线程池本地变量的传递的，还需要使用 TtlRunnable 的 get 方法来包裹一个 Runnable 对象，包裹对象时，通过 Holder，捕获 [captureAllTtlValues()] 父线程当前持有的所有 ThreadLocal。随后，子线程启动，在 Runnable 对象执行 run 方法之前 [beforeExecute()]，从 Holder 中取出 [replayCapturedTtlValue()] 先前捕获到的父线程所持有的 ThreadLocal 对象，并设置 [useValueInTtl()] 到当前子线程当中，设置之前会保存子线程原有的 ThreadLocal 作为 backUp，当子线程执行结束后，通过 backUp 恢复 [restoreTtlValueBeforeReplay()] 其原有的ThreadLocal。
 */
public class TTransmittableThreadLocal<T> extends InheritableThreadLocal<T> implements TtlCopier<T> {
    private static InheritableThreadLocal<WeakHashMap<TransmittableThreadLocal<Object>, ?>> holder = new InheritableThreadLocal<WeakHashMap<TransmittableThreadLocal<Object>, ?>>() {
        protected WeakHashMap<TransmittableThreadLocal<Object>, ?> initialValue() {
            return new WeakHashMap();
        }

        protected WeakHashMap<TransmittableThreadLocal<Object>, ?> childValue(WeakHashMap<TransmittableThreadLocal<Object>, ?> parentValue) {
            return new WeakHashMap(parentValue);
        }
    };

    @Override
    public T copy(T t) {
        return parentValue;
    }

}
